<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>state模式 &mdash; programming v0.1 documentation</title>
    <link rel="stylesheet" href="../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '0.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="top" title="programming v0.1 documentation" href="../index.html" />
    <link rel="up" title="设计模式学习笔记" href="index.html" />
    <link rel="next" title="proxy模式" href="proxy.html" />
    <link rel="prev" title="composite模式" href="composite.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="proxy.html" title="proxy模式"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="composite.html" title="composite模式"
             accesskey="P">上一页</a> |</li>
        <li><a href="../index.html">programming v0.1 documentation</a> &raquo;</li>
          <li><a href="index.html" accesskey="U">设计模式学习笔记</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="state">
<h1>state模式<a class="headerlink" href="#state" title="永久链接至标题">¶</a></h1>
<div class="section" id="id1">
<span id="index-11"></span><span id="id2"></span><h2>state模式定义<a class="headerlink" href="#id1" title="永久链接至标题">¶</a></h2>
<p><strong>The State Pattern</strong> allows an object to alter its behavior when its internal
state changes. The object will appear to change its class.</p>
<p><strong>状态模式</strong> 允许一个对象当其内部状态更改时来更改其行为.
对象会表现为更改自己的类.</p>
</div>
<div class="section" id="id3">
<h2>问题描述<a class="headerlink" href="#id3" title="永久链接至标题">¶</a></h2>
<p>模拟TCP的建立过程,状态图如下:</p>
<img alt="../_images/tcp_connection.jpg" src="../_images/tcp_connection.jpg" />
<p><strong>状态模式</strong> 的类图如下:</p>
<img alt="../_images/state_class.png" src="../_images/state_class.png" />
</div>
<div class="section" id="id4">
<h2>具体代码<a class="headerlink" href="#id4" title="永久链接至标题">¶</a></h2>
<p>下载请点击 <a href="../_downloads/state.cpp"><strong class="xref">这里</strong></a></p>
<div class="highlight-c++"><table class="highlighttable"><tr><td class="linenos"><pre>  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149</pre></td><td class="code"><div class="highlight"><pre><span class="c">/*</span>
<span class="c"> * Author: Tower Joo&lt;zhutao.iscas@gmail.com&gt;</span>
<span class="c"> * Time: 2009-06-11 14:32</span>
<span class="c"> * File: state.cpp</span>
<span class="c"> * Description: This source file is to implement the state design pattern.</span>
<span class="c"> */</span>

<span class="cp">#include &lt;iostream&gt;</span>
<span class="cp">#include &lt;string&gt;</span>
<span class="cp">#include &lt;vector&gt;</span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">TCPconnection</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">State</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="k">virtual</span> <span class="kt">void</span> <span class="n">Open</span><span class="p">(){}</span>
        <span class="k">virtual</span> <span class="kt">void</span> <span class="n">Close</span><span class="p">(){}</span>
        <span class="k">virtual</span> <span class="kt">void</span> <span class="n">Acknowledge</span><span class="p">(){}</span>
<span class="p">};</span>



<span class="k">class</span> <span class="nc">TCPopen</span><span class="o">:</span><span class="k">public</span> <span class="n">State</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">TCPconnection</span> <span class="o">*</span><span class="n">tcp</span><span class="p">;</span>
        <span class="n">TCPopen</span><span class="p">(</span><span class="n">TCPconnection</span><span class="o">*</span> <span class="n">tcp</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">tcp</span> <span class="o">=</span> <span class="n">tcp</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Open</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The Tcp is already opened.&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Acknowledge</span><span class="p">();</span>
        <span class="kt">void</span> <span class="n">Close</span><span class="p">();</span>
        
<span class="p">};</span>
<span class="k">class</span> <span class="nc">TCPclose</span><span class="o">:</span><span class="k">public</span> <span class="n">State</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">TCPconnection</span> <span class="o">*</span><span class="n">tcp</span><span class="p">;</span>
        <span class="n">TCPclose</span><span class="p">(</span><span class="n">TCPconnection</span><span class="o">*</span> <span class="n">tcp</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">tcp</span> <span class="o">=</span> <span class="n">tcp</span><span class="p">;</span>
        <span class="p">}</span>
        
        <span class="kt">void</span> <span class="n">Acknowledge</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The Tcp is not opened yet.&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Close</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The Tcp is already close.&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Open</span><span class="p">();</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">TCPacknowledge</span><span class="o">:</span><span class="k">public</span> <span class="n">State</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">TCPconnection</span> <span class="o">*</span><span class="n">tcp</span><span class="p">;</span>
        <span class="n">TCPacknowledge</span><span class="p">(</span><span class="n">TCPconnection</span><span class="o">*</span> <span class="n">tcp</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">tcp</span> <span class="o">=</span> <span class="n">tcp</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Open</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The Tcp is already open&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Acknowledge</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The Tcp is already acknowleged.&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Close</span><span class="p">();</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">TCPconnection</span>
<span class="p">{</span>
    <span class="k">public</span><span class="o">:</span>
        <span class="n">State</span> <span class="o">*</span><span class="n">state</span><span class="p">;</span>
        <span class="n">TCPconnection</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">state</span> <span class="o">=</span> <span class="k">new</span> <span class="n">TCPclose</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Open</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">state</span><span class="o">-&gt;</span><span class="n">Open</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Close</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">state</span><span class="o">-&gt;</span><span class="n">Close</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">Acknowledge</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="n">state</span><span class="o">-&gt;</span><span class="n">Acknowledge</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="kt">void</span> <span class="n">setState</span><span class="p">(</span><span class="n">State</span> <span class="o">*</span><span class="n">state</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="k">this</span><span class="o">-&gt;</span><span class="n">state</span> <span class="o">=</span> <span class="n">state</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="n">State</span><span class="o">*</span> <span class="n">getTCPclose</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="k">new</span> <span class="n">TCPclose</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="n">State</span><span class="o">*</span> <span class="n">getTCPopen</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="k">new</span> <span class="n">TCPopen</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="n">State</span><span class="o">*</span> <span class="n">getTCPacknowledge</span><span class="p">()</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="k">new</span> <span class="n">TCPacknowledge</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
        <span class="p">}</span>
<span class="p">};</span>
<span class="c">// because the classes have cross-reference</span>
<span class="c">// so the following methods MUST be defined after TCPconnection</span>
<span class="kt">void</span> <span class="n">TCPopen</span><span class="o">::</span><span class="n">Acknowledge</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The Tcp is acknowleged.&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
    <span class="n">tcp</span><span class="o">-&gt;</span><span class="n">setState</span><span class="p">(</span><span class="n">tcp</span><span class="o">-&gt;</span><span class="n">getTCPacknowledge</span><span class="p">());</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">TCPopen</span><span class="o">::</span><span class="n">Close</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;Yeah. The Tcp is close.&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
    <span class="n">tcp</span><span class="o">-&gt;</span><span class="n">setState</span><span class="p">(</span><span class="n">tcp</span><span class="o">-&gt;</span><span class="n">getTCPclose</span><span class="p">());</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">TCPclose</span><span class="o">::</span><span class="n">Open</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The Tcp is open&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
    <span class="n">tcp</span><span class="o">-&gt;</span><span class="n">setState</span><span class="p">(</span><span class="n">tcp</span><span class="o">-&gt;</span><span class="n">getTCPopen</span><span class="p">());</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">TCPacknowledge</span><span class="o">::</span><span class="n">Close</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">&quot;The Tcp is closed.&quot;</span><span class="o">&lt;&lt;</span><span class="n">endl</span><span class="p">;</span>
    <span class="n">tcp</span><span class="o">-&gt;</span><span class="n">setState</span><span class="p">(</span><span class="n">tcp</span><span class="o">-&gt;</span><span class="n">getTCPclose</span><span class="p">());</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">TCPconnection</span> <span class="n">tcp</span><span class="p">;</span>
    <span class="n">tcp</span><span class="p">.</span><span class="n">state</span><span class="o">-&gt;</span><span class="n">Open</span><span class="p">();</span>
    <span class="n">tcp</span><span class="p">.</span><span class="n">state</span><span class="o">-&gt;</span><span class="n">Acknowledge</span><span class="p">();</span>
    <span class="n">tcp</span><span class="p">.</span><span class="n">state</span><span class="o">-&gt;</span><span class="n">Close</span><span class="p">();</span>

    <span class="n">tcp</span><span class="p">.</span><span class="n">state</span><span class="o">-&gt;</span><span class="n">Acknowledge</span><span class="p">();</span><span class="c">// will not acknowleged, since the tcp is not open</span>
	<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>输出结果为:</p>
<div class="highlight-python"><pre>The Tcp is open
The Tcp is acknowleged.
The Tcp is closed.
The Tcp is not opened yet.</pre>
</div>
</div>
<div class="section" id="id5">
<h2>面对新的需要<a class="headerlink" href="#id5" title="永久链接至标题">¶</a></h2>
<p>如果有新的状态加入,只需要:</p>
<ul class="simple">
<li>继承State类</li>
<li>根据相应的状态图来实现相应的方法</li>
</ul>
</div>
<div class="section" id="id6">
<h2>更多注意<a class="headerlink" href="#id6" title="永久链接至标题">¶</a></h2>
<p>注意 <a class="reference internal" href="#id1"><em>State模式</em></a> 与 <a class="reference external" href="strategy.html#id1"><em>strategy模式</em></a> 的区别与联系:</p>
<ul>
<li><p class="first">二者的类图几乎完全相同</p>
</li>
<li><p class="first">目的不同:</p>
<blockquote>
<ul class="simple">
<li>可以把state模式看作是 <strong>将很多种条件(情况)放在特定的上下文中</strong>, 对于特定的 <strong>状态图</strong> (状态是明确的)</li>
<li>可以把strategy模式看作是 <strong>继承的一种可扩展(弹性)的选择</strong>, 对于可能的 <strong>算法</strong></li>
</ul>
</blockquote>
</li>
</ul>
<p><strong>状态模式</strong> 的好处:</p>
<ul class="simple">
<li>取代的繁琐的条件语句</li>
<li>易于扩展</li>
<li>耦合少(使用状态的client对于状态是解耦合的)</li>
</ul>
<p>但是使用 <strong>状态模式</strong> 可能会导致大量的类.</p>
</div>
<div class="section" id="id7">
<h2>参考更多<a class="headerlink" href="#id7" title="永久链接至标题">¶</a></h2>
<ol class="arabic simple">
<li><a class="reference external" href="http://en.wikipedia.org/wiki/State_pattern">State_Pattern</a></li>
</ol>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="../index.html">內容目录</a></h3>
            <ul>
<li><a class="reference external" href="">state模式</a><ul>
<li><a class="reference external" href="#id1">state模式定义</a></li>
<li><a class="reference external" href="#id3">问题描述</a></li>
<li><a class="reference external" href="#id4">具体代码</a></li>
<li><a class="reference external" href="#id5">面对新的需要</a></li>
<li><a class="reference external" href="#id6">更多注意</a></li>
<li><a class="reference external" href="#id7">参考更多</a></li>
</ul>
</li>
</ul>

            <h4>上一个主题</h4>
            <p class="topless"><a href="composite.html"
                                  title="上一章">composite模式</a></p>
            <h4>下一个主题</h4>
            <p class="topless"><a href="proxy.html"
                                  title="下一章">proxy模式</a></p>
            <h3>本页</h3>
            <ul class="this-page-menu">
              <li><a href="../_sources/designpattern/state.txt"
                     rel="nofollow">显示源代码</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>快速搜索</h3>
              <form class="search" action="../search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="搜索" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              输入相关的模块，术语，类或者函数名称进行搜索
              </p>
          </div>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="proxy.html" title="proxy模式"
             >下一页</a> |</li>
        <li class="right" >
          <a href="composite.html" title="composite模式"
             >上一页</a> |</li>
        <li><a href="../index.html">programming v0.1 documentation</a> &raquo;</li>
          <li><a href="index.html" >设计模式学习笔记</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; 版权所有 2009, zhutao.iscas@gmail.com.
      使用 <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.1.
    </div>
  </body>
</html>